#!/usr/bin/perl




use Getopt::Long;
use Cwd;

Getopt::Long::Configure ("bundling");






my $ref ="bash --posix";
my $mybin = "../42sh";
my $categories = 0;
my $e = 0;
my $selec = 0;
my $number = 0;
my $all = 0;
my $usage = 0;
my $succes = 0;
my $pathname = cwd();
my $global_percentage = 0;
my $average = 0;
my $nb_succes = 0;
my $nb_occurence = 0;
my $nb_file = 0;


sub treat_categories
{
    my $i = 0;
    $succes = 0;
    my $categorie = $_[0];

    print "Categorie : $categorie -> ";

    opendir (D, $pathname."/".$categorie);
    @current = readdir(D);
    foreach $f (@current)
    {
	next if $f eq "." or $f eq ".." or $f eq ".svn";

	if (-f $pathname."/".$categorie."/".$f)
	{
	    open(CMD, $pathname."/".$categorie."/".$f)
		or die "Can't open ./$categorie/$f";
	    @cmd = <CMD>;
	    check($cmd[0]);
	    $i++;
	    close(CMD);
	}
	$percentage = ($succes * 100) / $i;

	closedir R;
    }
    $percentage = int($percentage);
    print "\033[;33m$percentage%\n";
    print "\033[00m";
}


sub check
{
    $tst = $_[0];
    $tst =~ s/\n//g;

    $tst ="'".$tst."'";
    my $c = "-c";
    my $cmd = $mybin ." " . $c . " " . $tst;

    qx{$cmd > mysh.out 2> mysh.err};
    my $my_ret = ($? % 255);
    my $my_out = `cat -e mysh.out`;
    my $my_err = qx{cat -e mysh.err};

    my $cmdb = $ref." ".$c." ".$tst;

    qx{$cmdb > ref.out 2> ref.err};
    my $ref_ret = ($? % 255);
    my $ref_out = `cat -e ref.out`;
    my $ref_err = `cat -e ref.err`;


    $my_out =~ s/(42sh$) //g;
    $my_err =~ s/(42sh$) //g;
    $ref_out =~ s/bash://g;
    $ref_err =~ s/bash://g;

    $succes++ if (($my_out eq $ref_out));

}


sub treat_all
{
    my $i = 0;
    $succes = 0;
    $categorie = $_[0];
    opendir (D, $pathname."/".$categorie);
    @current = readdir(D);
    foreach $f (@current)
    {
	next if $f eq "." or $f eq ".." or $f eq ".svn" or $f eq "src";

	if (-f $pathname."/".$categorie."/".$f)
	{
	    open(CMD, $pathname."/".$categorie."/".$f)
		or die "Erreur d'ouverture de ./$categorie/$f";
	    @cmd = <CMD>;
	    print "\033[00m";
	    $cmd[0] =~ s/\n//g;
	    printf "\033[36m> Test $i\033[00m: $cmd[0]";
	    check_all($cmd[0]);
	    $i++;
	    close(CMD);
	    print "-------------------------------------------------------------------------------------\n";
	}
    }
    $nb_file += $i;
    $percentage = ($succes * 100) / $i;
    $percentage = int($percentage);
    $average += $percentage;
    print "\033[00m\n\033[36m Percentage\033[00m: \033[1;32m$percentage%\n\n\033[00m ";
    closedir R;
}


sub check_all
{
    $tst = $_[0];
    $tst =~ s/\n//g;

    $tst ="'".$tst."'";
    my $c = "-c";
    my $cmd = $mybin ." " . $c . " " . $tst;

    qx{$cmd > mysh.out 2> mysh.err};
    my $my_ret = ($? % 256);
    my $my_out = `cat -e mysh.out`;
    $my_err = qx{cat -e mysh.err};

    my $cmdb = $ref." ".$c." ".$tst;

    qx{$cmdb > ref.out 2> ref.err};
    my $ref_ret = ($? % 255);
    $ref_out = `cat -e ref.out`;
    $ref_err = `cat -e ref.err`;


    $my_out =~ s/(42sh$) //g;
    $my_err =~ s/(42sh$) //g;
    $ref_out =~ s/bash://g;
    $ref_err =~ s/bash://g;

    if ($my_out eq $ref_out)
    {
	printf "\e[01m\033[1;32m OK\033[00m\n";
	$succes++;
    }
    else
    {
	print "\033[5;31m KO\033[00m\n";
	#if ($my_ret != $ref_ret)
	#{
	 #   print "\n\n\033[;33m     * 42SH Ret:\033[00m $my_ret\n";
	  #  print "\033[;33m       BASH Ret:\033[00m $ref_ret\n\n";
	#}
	if ($my_out ne $ref_out)
	{
	    qx{sed 's/bash://g' ref.out > ref2.out};
	    qx{sed 's/(42sh$) //g' mysh.out > mysh2.out};
	    qx{diff -u mysh2.out ref2.out > diffstd};
	    $diff_out = `cat diffstd`;
	    print "\n\n\033[;33m     * Different Standard Output :\033[00m \n\n $diff_out\n";
	}
	#if ($my_err ne $ref_err)
	#{
	 #   qx{sed 's/bash://g' ref.err > ref2.err };
	  #  qx{sed 's/(42sh$) //g' mysh.err > mysh2.err};
	   # qx{diff -u mysh2.err ref2.err > differr};
	    #$diff_err = `cat differr`;
	    #print "\n\033[;33m     *Different Standard Error:\033[00m $diff_err\n";
	#}
    }
}


sub treat_final
{
    $nb_succes = 0;
    $categorie = $_[0];
    my $i = 0;

    opendir (D, $pathname."/".$categorie);
    @current = readdir(D);
    foreach $f (@current)
    {
	next if $f eq "." or $f eq ".." or $f eq ".svn" ;

	if (-f $pathname."/".$categorie."/".$f)
	{
	    open(CMD, $pathname."/".$categorie."/".$f)
		or die "Can't open the directory: ./$categorie/$f";
	    @cmd = <CMD>;
	    print "\033[00m";
	    $cmd[0] =~ s/\n//g;
	    check_number($cmd[0]);
	    $i++;
	    close(CMD);
	}
    }
    $nb_file++;
    $percentage = ($nb_succes * 100) / $i;
    $percentage = int($percentage);
    $average += $percentage;
    closedir R;
}


sub treat_number
{
    my $categorie = $_[0];
    opendir (D, $pathname."/".$categorie);
    @current = readdir(D);
    foreach $f (@current)
    {
	next if $f eq "." or $f eq ".." or $f eq ".svn" ;

	if (-f $pathname."/".$categorie."/".$f)
	{
	    open(CMD, $pathname."/".$categorie."/".$f)
		or die "Can't open directory ./$categorie/$f";
	    @cmd = <CMD>;
	    $cmd[0] =~ s/\n//g;
	    check_number($cmd[0]);
	    $nb_occurence++;
	    close(CMD);
	}
    }
    $nb_file += nb_occurence;
    closedir R;
}


sub check_number
{
    $tst = $_[0];
    $tst =~ s/\n//g;

    $tst ="'".$tst."'";
    my $c = "-c";
    my $cmd = $mybin ." " . $c . " " . $tst;

    qx{$cmd > 42sh.out 2> 42sh.err};
    my $my_ret = ($? / 256);
    my $my_out = `cat 42sh.out`;
    $my_err = qx{cat 42sh.err};

    my $cmdb = $ref." ".$c." ".$tst;

    qx{$cmdb > ref.out 2> ref.err};
    my $ref_ret = ($? % 255);
    $ref_out = `cat ref.out`;
    $ref_err = `cat ref.err`;

    $my_out =~ s/(42sh$) //g;
    $my_err =~ s/(42sh$) //g;
    $ref_out =~ s/bash://g;
    $ref_err =~ s/bash://g;


    if ($my_out eq $ref_out)
    {
	$nb_succes++;
    }
}


@repertories ;
opendir (R, $pathname);
@list = readdir(R);
foreach $f (@list)
{
    next if $f eq "." or $f eq ".." or $f eq ".svn";
    if (-d $f)
    {
	push (@repertories, $f);
    }
}
closedir R;


if (@ARGV == 0)
{
    main_all(@repertories);
}


my $time = 0.0;



sub main_categories
{
    print "\n\n\n\e[01m\033[36m       [Pourcentage of successful tests by categories]\n\n\n\033[00m";

    foreach $cat (@_)
    {
	treat_categories($cat);
    }
    print "\033[00m\n";
}


sub main_all
{
    $global_percentage = 0;
    $average = 0;
    $nb_file = 0;

    print "\n\n\n\e[01m\033[36m                               [Displaying ALL the checks]\n\n";
    foreach $cat (@_)
    {
	next if ($cat eq "src");
	print "\e[01m \033[36m \n\nCategorie: $cat\n\n";
	treat_all($cat);
    }
    my $taille = scalar(@_) - 1;

    $global_percentage = $average / ($taille + 1);

    $global_percentage = int($global_percentage);

    print "\n\033[36m Global percentage of succesfull tests\033[00m:\033[1;32mC $global_percentage%\n\n\033[00m";
}


sub main_select
{
    $average = 0;
    $global_percentage = 0;
    my $i = 0;
    $i = #@select;
    print "\n\n\e[01m\033[36m        [Check on the selected Categories]\n\n";
    foreach $cat (@$select)
    {
	print " \n\nCategorie: $cat\n\n";
	treat_all($cat);
    }
    my $taille = scalar(@$select);
    $global_percentage = $average / $taille ;

    print "\033[00m Global percentage Of Succesfull tests\033[00m:\033[5;33m $global_percentage%\n\n\033[00m";

}


sub main_number
{
    $nb_succes = 0;
    $nb_occurence = 0;
    print "\n\n\n\n\n\e[01m\033[36m         [Number of successful tests on the total number of tests]\n\n\n";
    foreach $cat (@_)
    {
	treat_number($cat);
    }
    print "\033[00m\n\033[1;32m                $nb_succes\033[00m tests have succed on a total of\033[1;32m $nb_occurence\033[00m tests\n\n\n\n\n ";
}


sub main_final
{
    $nb_file = 0;
    $nb_succes = 0;
    $global_percentage = 0;
    $average = 0;

    print "\n\n\n\n\033[36m \e[01m            [Percentage of successful tests for all the tests.]\n\n";
    foreach $cat (@_)
    {
	next if $cat eq "src";
	treat_final($cat);
    }

    $global_percentage = $average / $nb_file;
    $global_percentage = int($global_percentage);
    print "\n                                    \033[1;32m $global_percentage%\n\n\033[00m\n\n";

}

GetOptions
    (
     'categories|c' => \$categories,
     'select|e=s@'  => \$select,
     'final|f'  => \$final,
     'number|n'  => \$number,
     'all|a'   => \$all,
     'help|h'   => \$usage,
     'time|t=f'   => \$time,
    );


sub print_usage
{
    print "\nUsage : ./check [Options]\n\n";
    print "Options : \n
-c or --categories
-e <category> or --select <category>
-f or --final
-a or --all\n";
}


&print_usage if ($usage);

&main_categories(@repertories) if ($categories);

&main_all(@repertories) if ($all);

&main_select if (@$select);

&main_final(@repertories) if ($final);

&main_number(@repertories) if ($number);


qx{rm -f *.err *.out diff*};
